Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / MeshChatX.git / files / docs / meshchatx_linux_sandbox.md

Displaying Raw • View renderedDownload


docs/meshchatx_linux_sandbox.md e8e5128bc67cd3e8540bcd9f4e9be1b8d43db36a (e8e5128b) Text, 6.37 KB

Tc9d1d9# MeshChatX on Linux: Firejail and Bubblewrap

This page shows how to run Ta5d6ff`meshchat` under **Firejail** or **Bubblewrap** (Ta5d6ff`bwrap`) on Linux. Use this when you install MeshChatX natively (wheel, package, or Poetry) and want an extra layer of filesystem and process isolation compared to running the binary directly.

These tools do **not** replace a full virtual machine or hardware-enforced boundary. They reduce exposure of your home directory and other paths the process can write to, when you configure them with tight whitelists or bind mounts.

**Containers:** If you already run MeshChatX with Docker or Podman, that is a different isolation model; this document is aimed at **host-installed** Ta5d6ff`meshchat`.

Tc9d1d9## Prerequisites

Install one or both from your distribution:

Tff7b72- **Firejail:** package name is usually Ta5d6ff`firejail`.
Tff7b72- **Bubblewrap:** package name is usually Ta5d6ff`bubblewrap`; the binary is Ta5d6ff`bwrap`.

You need a working Ta5d6ff`meshchat` on your Ta5d6ff`PATH` (for example after Ta5d6ff`pipx install`, Ta5d6ff`pip install --user`, or a distro package).

Pick a **dedicated data directory** for sandboxed runs so you do not mix permissions or policies with a non-sandboxed install. The examples below use:

Ta5d6ff```Ta5d6ffbash
Te6edf3DATATff7b72=Ta5d6ff"Tffd700${Te6edf3XDG_DATA_HOMETff7b72:-Te6edf3$HOMETb4b4b4/.local/shareTffd700}Ta5d6ff/meshchatx-sandboxTa5d6ff"
mkdir -p Ta5d6ff"Te6edf3$DATATa5d6ff/storageTa5d6ff" Ta5d6ff"Te6edf3$DATATa5d6ff/.reticulumTa5d6ff"
Ta5d6ff```

Adjust paths if you prefer another location.

Tc9d1d9## Firejail

Firejail applies a profile (or defaults) on top of your command. For MeshChatX you typically want:

Tff7b72- **Network** left available so Reticulum and the web UI can work (do not use Ta5d6ff`--net=none` unless you know you need it).
Tff7b72- **Writable** only your chosen data directory (and anything else the app truly needs).

Tc9d1d9### Installed `meshchat` (pip, pipx, or system package)

Ta5d6ff```Ta5d6ffbash
Te6edf3DATATff7b72=Ta5d6ff"Tffd700${Te6edf3XDG_DATA_HOMETff7b72:-Te6edf3$HOMETb4b4b4/.local/shareTffd700}Ta5d6ff/meshchatx-sandboxTa5d6ff"
mkdir -p Ta5d6ff"Te6edf3$DATATa5d6ff/storageTa5d6ff" Ta5d6ff"Te6edf3$DATATa5d6ff/.reticulumTa5d6ff"

firejail --quiet Tffea00\
--whitelistTff7b72=Ta5d6ff"Te6edf3$DATATa5d6ff" Tffea00\
meshchat --headless --host T79c0ff127.0.0.1 Tffea00\
--storage-dirTff7b72=Ta5d6ff"Te6edf3$DATATa5d6ff/storageTa5d6ff" Tffea00\
--reticulum-config-dirTff7b72=Ta5d6ff"Te6edf3$DATATa5d6ff/.reticulumTa5d6ff"
Ta5d6ff```

If the default profile blocks something MeshChatX needs, you can start from a looser base and tighten later, for example:

Ta5d6ff```Ta5d6ffbash
firejail --noprofile --whitelistTff7b72=Ta5d6ff"Te6edf3$DATATa5d6ff" Tffea00\
meshchat --headless --host T79c0ff127.0.0.1 Tffea00\
--storage-dirTff7b72=Ta5d6ff"Te6edf3$DATATa5d6ff/storageTa5d6ff" Tffea00\
--reticulum-config-dirTff7b72=Ta5d6ff"Te6edf3$DATATa5d6ff/.reticulumTa5d6ff"
Ta5d6ff```

Ta5d6ff`--noprofile` disables many Firejail restrictions; treat it as a stepping stone, not the final hardening.

Tc9d1d9### From source with Poetry

Poetry needs the project tree and the virtualenv. Example:

Ta5d6ff```Ta5d6ffbash
Tffa657cd /path/to/reticulum-meshchatX
Te6edf3DATATff7b72=Ta5d6ff"Tffd700${Te6edf3XDG_DATA_HOMETff7b72:-Te6edf3$HOMETb4b4b4/.local/shareTffd700}Ta5d6ff/meshchatx-sandboxTa5d6ff"
Te6edf3VENVTff7b72=Ta5d6ff"Tff7b72$(poetry env info -pTff7b72)Ta5d6ff"
mkdir -p Ta5d6ff"Te6edf3$DATATa5d6ff/storageTa5d6ff" Ta5d6ff"Te6edf3$DATATa5d6ff/.reticulumTa5d6ff"

firejail --quiet Tffea00\
--whitelistTff7b72=Ta5d6ff"Tff7b72$(Tffa657pwdTff7b72)Ta5d6ff" Tffea00\
--whitelistTff7b72=Ta5d6ff"Te6edf3$VENVTa5d6ff" Tffea00\
--whitelistTff7b72=Ta5d6ff"Te6edf3$DATATa5d6ff" Tffea00\
poetry run meshchat --headless --host T79c0ff127.0.0.1 Tffea00\
--storage-dirTff7b72=Ta5d6ff"Te6edf3$DATATa5d6ff/storageTa5d6ff" Tffea00\
--reticulum-config-dirTff7b72=Ta5d6ff"Te6edf3$DATATa5d6ff/.reticulumTa5d6ff"
Ta5d6ff```

You may need extra Ta5d6ff`--whitelist=` entries if Poetry or dependencies read config elsewhere (for example under Ta5d6ff`$HOME/.config`).

Tc9d1d9### USB serial (RNode or similar)

If Reticulum talks to a radio over a serial device, Firejail may need explicit access to TTY devices, for example:

Ta5d6ff```Ta5d6ffbash
firejail --noblacklistTff7b72=/dev/ttyACM0 --noblacklistTff7b72=/dev/ttyUSB0 Tffea00\
...
Ta5d6ff```

Use the device nodes your system actually exposes (Ta5d6ff`dmesg`, Ta5d6ff`ls /dev/tty*`).

Tc9d1d9## Bubblewrap (`bwrap`)

Bubblewrap does not ship profiles; you list every mount and option. The pattern below keeps the **whole root filesystem read-only**, mounts a **writable tmpfs** on Ta5d6ff`/tmp`, and makes **only** your data directory writable at its normal path. **Network namespaces are not changed**, so Reticulum and TCP/UDP behave like an unsandboxed process unless you add Ta5d6ff`--unshare-net` (which usually breaks mesh networking).

Tc9d1d9### Installed `meshchat`

Ta5d6ff```Ta5d6ffbash
Te6edf3DATATff7b72=Ta5d6ff"Tffd700${Te6edf3XDG_DATA_HOMETff7b72:-Te6edf3$HOMETb4b4b4/.local/shareTffd700}Ta5d6ff/meshchatx-sandboxTa5d6ff"
mkdir -p Ta5d6ff"Te6edf3$DATATa5d6ff/storageTa5d6ff" Ta5d6ff"Te6edf3$DATATa5d6ff/.reticulumTa5d6ff"

Tffa657exec bwrap Tffea00\
--die-with-parent Tffea00\
--new-session Tffea00\
--proc /proc Tffea00\
--dev /dev Tffea00\
--ro-bind / / Tffea00\
--tmpfs /tmp Tffea00\
--bind Ta5d6ff"Te6edf3$DATATa5d6ff" Ta5d6ff"Te6edf3$DATATa5d6ff" Tffea00\
--uid Ta5d6ff"Tff7b72$(id -uTff7b72)Ta5d6ff" --gid Ta5d6ff"Tff7b72$(id -gTff7b72)Ta5d6ff" Tffea00\
meshchat --headless --host T79c0ff127.0.0.1 Tffea00\
--storage-dirTff7b72=Ta5d6ff"Te6edf3$DATATa5d6ff/storageTa5d6ff" Tffea00\
--reticulum-config-dirTff7b72=Ta5d6ff"Te6edf3$DATATa5d6ff/.reticulumTa5d6ff"
Ta5d6ff```

Notes:

Tff7b72- If Ta5d6ff`meshchat` lives only inside a venv that is **not** under Ta5d6ff`$DATA`, the read-only root still allows **reading** that path; you do not have to bind-mount the venv separately unless you also need writes there.
Tff7b72- Distributions that merge Ta5d6ff`/` and Ta5d6ff`/usr` (merged-usr) still work with Ta5d6ff`--ro-bind / /` on typical glibc setups. If Ta5d6ff`bwrap` fails with missing library paths, add the extra Ta5d6ff`--ro-bind` lines your distro documents (for example Ta5d6ff`/lib64`).

Tc9d1d9### From source with Poetry

Bind the repository and the Poetry venv read-only, and keep Ta5d6ff`DATA` writable:

Ta5d6ff```Ta5d6ffbash
Tffa657cd /path/to/reticulum-meshchatX
Te6edf3DATATff7b72=Ta5d6ff"Tffd700${Te6edf3XDG_DATA_HOMETff7b72:-Te6edf3$HOMETb4b4b4/.local/shareTffd700}Ta5d6ff/meshchatx-sandboxTa5d6ff"
Te6edf3VENVTff7b72=Ta5d6ff"Tff7b72$(poetry env info -pTff7b72)Ta5d6ff"
mkdir -p Ta5d6ff"Te6edf3$DATATa5d6ff/storageTa5d6ff" Ta5d6ff"Te6edf3$DATATa5d6ff/.reticulumTa5d6ff"
Te6edf3PROJTff7b72=Ta5d6ff"Tff7b72$(Tffa657pwdTff7b72)Ta5d6ff"

Tffa657exec bwrap Tffea00\
--die-with-parent Tffea00\
--new-session Tffea00\
--proc /proc Tffea00\
--dev /dev Tffea00\
--ro-bind / / Tffea00\
--tmpfs /tmp Tffea00\
--bind Ta5d6ff"Te6edf3$DATATa5d6ff" Ta5d6ff"Te6edf3$DATATa5d6ff" Tffea00\
--ro-bind Ta5d6ff"Te6edf3$PROJTa5d6ff" Ta5d6ff"Te6edf3$PROJTa5d6ff" Tffea00\
--ro-bind Ta5d6ff"Te6edf3$VENVTa5d6ff" Ta5d6ff"Te6edf3$VENVTa5d6ff" Tffea00\
--uid Ta5d6ff"Tff7b72$(id -uTff7b72)Ta5d6ff" --gid Ta5d6ff"Tff7b72$(id -gTff7b72)Ta5d6ff" Tffea00\
--setenv PATH Ta5d6ff"Te6edf3$VENVTa5d6ff/bin:Te6edf3$PATHTa5d6ff" Tffea00\
--chdir Ta5d6ff"Te6edf3$PROJTa5d6ff" Tffea00\
poetry run meshchat --headless --host T79c0ff127.0.0.1 Tffea00\
--storage-dirTff7b72=Ta5d6ff"Te6edf3$DATATa5d6ff/storageTa5d6ff" Tffea00\
--reticulum-config-dirTff7b72=Ta5d6ff"Te6edf3$DATATa5d6ff/.reticulumTa5d6ff"
Ta5d6ff```

Ta5d6ff`poetry` itself must be reachable on Ta5d6ff`PATH` inside the sandbox (often under Ta5d6ff`/usr` or Ta5d6ff`$HOME/.local/bin`, both visible with Ta5d6ff`--ro-bind / /`). If Ta5d6ff`poetry run` fails because it cannot read Ta5d6ff`~/.config/poetry`, add a read-only bind for that directory or invoke the venv interpreter directly instead of Ta5d6ff`poetry run`:

Ta5d6ff```Ta5d6ffbash
Tffa657exec bwrap Tffea00\
... same mounts as above ... Tffea00\
--setenv PATH Ta5d6ff"Te6edf3$VENVTa5d6ff/bin:Te6edf3$PATHTa5d6ff" Tffea00\
--chdir Ta5d6ff"Te6edf3$PROJTa5d6ff" Tffea00\
meshchat --headless --host T79c0ff127.0.0.1 Tffea00\
--storage-dirTff7b72=Ta5d6ff"Te6edf3$DATATa5d6ff/storageTa5d6ff" Tffea00\
--reticulum-config-dirTff7b72=Ta5d6ff"Te6edf3$DATATa5d6ff/.reticulumTa5d6ff"
Ta5d6ff```

(Use the Ta5d6ff`meshchat` script or Ta5d6ff`python -m` entry point from Ta5d6ff`$VENV/bin` if your install exposes it there.)

Tc9d1d9### USB serial under Bubblewrap

You may need a clearer view of devices than the minimal Ta5d6ff`--dev /dev` provides. Options include Ta5d6ff`--dev-bind /dev /dev` (broader device exposure) or binding only the specific character device. Balance convenience against attack surface.


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────